package com.plian.system.service.cqzc.plan;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.cache.UserCache;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.constant.yth.YthConstant;
import com.plian.system.dao.bt.baseinfo.BaseInfoDao;

import com.plian.system.dao.cqzc.bondsPlan.BondsPlanDao;


import com.plian.system.dao.sys.orgzation.OrgzationDao;

import com.plian.system.entity.fr.bonds.BondsPlan;
import com.plian.system.entity.sys.ApprovalMessage;

import com.plian.system.mapper.fr.bonds.BondsPlanMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.model.page.Page;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.sys.message.IApprovalMessageService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.wf.FormWorkflowService;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import static com.plian.system.constant.sys.FormStatusConstant.*;
import static com.plian.system.constant.sys.FormTypeConstant.*;


/**
 * 说明：发债计划
 */
@Service
public class BondsPlanService extends ServiceImpl<BondsPlanMapper, BondsPlan> implements BaseFlowService {
    @Autowired
    BondsPlanDao bondsPlanDao;
    @Autowired
    FileService fileService;
    @Autowired
    OrgzationDao orgzationDao;
    @Autowired
    FormWorkflowService formWorkflowService;
    @Autowired
    IFormCodeService formCodeService;
    @Autowired
    BaseInfoDao baseInfoDao;
    @Autowired
    IOrgService orgService;

    @Autowired
    private IApprovalMessageService approvalMessageService;

    /**
     * logger属性.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(BondsPlanService.class);
    /**
     * 保存
     *
     * @param pd
     * @return
     */
    public ObjResult save(PageData pd) {
        try {
            String id = UuidUtil.get32UUID();
            pd.put("id", id);
            pd.put("status", "0");
            pd.put("orgId", TokenUtil.getTokenOrgId());
            pd.put("createDate", new Date());
            pd.put("formType", CQZC_BONDSPLAN);
            pd.put("code", formCodeService.getCode(CQZC_BONDSPLAN));
            pd.put("createUser", TokenUtil.getTokenUserId());
            pd.put("updateUser", TokenUtil.getTokenUserId());
            pd.put("updateTime", new Date());
            bondsPlanDao.save(pd);
            //保存附件
            fileService.saveAll(id, (List<HashMap>) pd.get("list_doc"));
            HashMap<String, Object> processVariable = new HashMap<>();
            formWorkflowService.startProcessAndSimulate(id, pd.getString("formType"), processVariable);
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 修改
     *
     * @param pd
     * @return
     */
    public ObjResult edit(PageData pd) {
        try {
            String id = pd.getString("id");
            pd.put("updateUser", TokenUtil.getTokenUserId());
            pd.put("updateTime", new Date());
            bondsPlanDao.edit(pd);
            //修改附件
            fileService.edit(id, (List<HashMap>) pd.get("list_doc"));
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 查询列表
     *
     * @return
     */
    public ListResult listPage(PageData pd) {
        ListResult listResult;
        try {
            pd.put("orgId", TokenUtil.getTokenOrgId());
            boolean isPage = true;
            if (pd.containsKey("isPage")) {
                isPage = (boolean) pd.get("isPage");
            }
            Page page = new Page(isPage, pd);
            List<PageData> list = bondsPlanDao.listPage(page);
            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(list);
            listResult.setTotal(page.getTotal());
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
        }
        return listResult;
    }

    /**
     * 根据id查询
     *
     * @param pd
     * @return
     */
    public ObjResult findbyid(PageData pd) {
        ObjResult objResult;
        String id = pd.getString("id");
        try {
            PageData p = bondsPlanDao.findbyid(id);
            objResult = new ObjResult(CommonCode.SUCCESS);
            objResult.setPageData(p);
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
            return objResult;
        }
    }

    public ObjResult del_ids(List<String> ids) {
        try {
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            bondsPlanDao.del_ids(ids);
            for (String s : ids) {
                formWorkflowService.deleteProcessInstance(s);
            }
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 提交单据
     *
     * @param formId 单据id
     */
    public HashMap<String, Object> commit(String formId){
        PageData pageData = new PageData();
        pageData.put("status", String.valueOf(FLOW));
        ArrayList<String> ids = new ArrayList<>();
        ids.add(formId);
        pageData.put("id", ids);
        try {
            bondsPlanDao.refer(pageData);
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException("提交失败");
        }
        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String, Object>();
    }

    /**
     * 退回单据
     *
     * @param formId 单据id
     */
    public Boolean reject(String formId, int formState, String comment){
        PageData pageData = new PageData();
        pageData.put("status", String.valueOf(formState));
        pageData.put("id", Collections.singletonList(formId));
        try {
            bondsPlanDao.refer(pageData);
            saveMessage(formId, false, comment);
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException("回退失败");
        }
        return true;
    }

    /**
     * 单据完成后
     *
     * @param formId
     */
    public Boolean finish(String formId) {
        try {
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(FINISH));
            pageData.put("id", Collections.singletonList(formId));
            bondsPlanDao.refer(pageData);
            saveMessage(formId, true, "审批通过");
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException(new ObjResult("单据流转完成时修改单据状态失败！"));
        }
        return true;
    }

    private void saveMessage(String formId, boolean approval, String comment) throws Exception{
        PageData pd = bondsPlanDao.findbyid(formId);
        String dataSource = pd.getString("dataSource");
        String dataSourceId = pd.getString("dataSourceId");
        if (YthConstant.DATA_NINGBO.equals(dataSource)) {
            ApprovalMessage approvalMessage = new ApprovalMessage();
            approvalMessage.setDataSourceType(YthConstant.DATA_NINGBO);
            approvalMessage.setFilingUserName(UserCache.userIdToName(TokenUtil.getTokenUserId()));
            approvalMessage.setFormType(CQZC_BONDSPLAN);
            approvalMessage.setDataSourceId(dataSourceId);
            approvalMessage.setOpinion(comment);
            approvalMessage.setIsApprove(approval ? 2 : 1);
            approvalMessage.setIsSend(1);
            approvalMessage.setFilingCode(pd.getString("code"));
            approvalMessageService.save(approvalMessage);
        }
    }

    public void goBackToStash(String formId) {
        try {
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(UNREVIEWED));
            pageData.put("id", Collections.singletonList(formId));
            bondsPlanDao.refer(pageData);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
        }
    }


    /**
     * @param formIds 单据ids
     */
    public List<PageData> findByIds(List<String> formIds) {
        try {
            PageData pageData = new PageData();
            pageData.put("ids", formIds);
            return bondsPlanDao.findByIds(pageData);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException(new ObjResult("根据单据id列表查询报表失败！"));
        }
    }

    @Override
    public List<Integer> getFormType() {
        return Arrays.asList(CQZC_BONDSPLAN);
    }


    public ListResult reportList(PageData pd) throws Exception {
        ListResult listResult;
        try {
            Page page = new Page(false, pd);
            List<PageData> list = bondsPlanDao.reportListPage(page);
            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(list);
            listResult.setTotal(page.getTotal());
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
        }
        return listResult;
    }



}